package ee.ut.math.chess.base.model;

import java.io.Serializable;
import java.util.Arrays;

import ee.ut.math.chess.base.model.chesspiece.Bishop;
import ee.ut.math.chess.base.model.chesspiece.ChessPiece;
import ee.ut.math.chess.base.model.chesspiece.Color;
import ee.ut.math.chess.base.model.chesspiece.King;
import ee.ut.math.chess.base.model.chesspiece.Knight;
import ee.ut.math.chess.base.model.chesspiece.Pawn;
import ee.ut.math.chess.base.model.chesspiece.Queen;
import ee.ut.math.chess.base.model.chesspiece.Rook;

public class Board implements Serializable{
	
	private static final long serialVersionUID = 1L;
	private ChessPiece[][] board;


	public void resetBoard() {
		board = new ChessPiece[8][8];
		buildBackRow(Color.WHITE, 0);
		buildPawnRow(Color.WHITE, 1);

		buildPawnRow(Color.BLACK, 6);
		buildBackRow(Color.BLACK, 7);
	}

	public ChessPiece getChessPiece(int x, int y) {
		return board[x][y];
	}

	public void moveChessPiece(int x1, int y1, int x2, int y2) {
		board[x2][y2] = board[x1][y1];
		board[x1][y1] = null;
	}

	public void removeChessPiece(int x, int y) {// needed for en passant
		board[x][y] = null;
	}

	private void buildPawnRow(Color color, int rowNum) {
		for (int i = 0; i < 8; i++) {
			board[rowNum][i] = new Pawn(color);
		}
	}

	private void buildBackRow(Color color, int rowNum) {
		board[rowNum][0] = new Rook(color);
		board[rowNum][1] = new Knight(color);
		board[rowNum][2] = new Bishop(color);
		board[rowNum][3] = new Queen(color);
		board[rowNum][4] = new King( color);
		board[rowNum][5] = new Bishop(color);
		board[rowNum][6] = new Knight(color);
		board[rowNum][7] = new Rook(color);
	}

	public ChessPiece[][] getBoard() {
		return board;
	}
	public void setBoard(ChessPiece[][] board) {
		this.board = board;
	}

	public String toJSON(Move checkMove) {
		if (checkMove != null) {
			setThreatening(checkMove.getStart(), true);
		}
		StringBuilder buffer = new StringBuilder();
		buffer.append("\n\t[");
		for (int i = 0; i < 8; i++) {
			if (i != 0) {
				buffer.append(",\n\t");
			}
			buffer.append(Arrays.toString(board[i]));
		}
		buffer.append("]");
		if (checkMove != null) {
			setThreatening(checkMove.getStart(), false);
		}
		return buffer.toString();
	}
	
	private void setThreatening(Position position, boolean isThreatening) { //only visual (client side implementation)
		board[position.getX()][position.getY()].setThreatening(isThreatening);		
	}

	public void move(Move move) {
		moveChessPiece(move.getX1(), move.getY1(), move.getX2(), move.getY2());
	}
	
	public void promote(int x, int y) {
		ChessPiece chessPiece = getChessPiece(x, y);
		if (chessPiece != null && chessPiece instanceof Pawn) {
			board[x][y] = new Queen(chessPiece.getColor());
		}
	}
}
